Repository navigation
Tests: compare values, not their display (P32) - #45
Merged
Merged
Conversation
An example passes when the expected text and the output are each one Python literal and equal with ==: 4 for 4.0, [1,2,30] for [1, 2, 30], "+" for '+'. Everything else, and an example with a comparison flag of its own, is checked as doctest does. The report keeps both texts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
«Tests» now compares values, not their display (P32). Only
src/runtime/doctests.pychanges: no protocol change, nothing in the macro or the IDE.Behaviour
When the expected text and the output are each one Python literal (numbers, strings, lists, tuples, dicts, sets,
True/False/None, nested), an example passes ifast.literal_eval(expected) == ast.literal_eval(got). So4for4.0,[1,2,30]for[1, 2, 30]and["+", 1, 2]for['+', 1, 2]pass.Everything else is compared as Python's doctest does, unchanged:
<function f at 0x…>;set().The report is unchanged too:
Expected/Gotshow the texts as written. The counts, the coverage, the print hint and the «lacks blank after >>>» hint stay as they are.Decisions
_GlpythonOutputChecker(doctest.OutputChecker), passed to ourDocTestRunneraschecker.check_outputfirst asks doctest's own check; only if that fails does it compare values. So nothing that passed before can fail now.output_difference(the report text) is doctest's own, unchanged.ast.literal_evalmust accept it. Any error (SyntaxError,ValueError, deep nesting, too many digits) means: no value comparison.doctest.COMPARISON_FLAGS:ELLIPSIS,NORMALIZE_WHITESPACE,DONT_ACCEPT_TRUE_FOR_1,IGNORE_EXCEPTION_DETAIL, …), only doctest's check applies. Whoever sets a flag asked for doctest's comparison;DONT_ACCEPT_TRUE_FOR_1in particular contradictsTrue == 1.print: what was printed is compared the same way as a displayed value, soprint(5)now passes for5.0, asreturn 5does. Todayprint(5)andreturn 5both pass for5; that stays, and the print hint («probablyreturn») still appears for every example that passes throughprint. Text output that isn't a literal (print("Hallo")→Hallo) is compared as text, as before.0.3for0.1 + 0.2fails, because==isFalse.True/1: passes in both directions, becauseTrue == 1in Python. doctest itself already acceptedTruefor an expected1. Also equal now:1e3/1000,-0.0/0,1_000/1000.return '4'for an expected4still fails ('4' != 4).Checks
check-runtime-doctests.py(intest:runtime) has a new section. It covers every case from P32 and the edge cases:4for8 / 2;5.0for5[1,2,30]for[1, 2, 30];"+"for'+'["+", 1, ["*", 2, 3]]for the same value with'…'Nonewith other spacingTruefor1, and1forTrue0.3for0.1 + 0.2;4for'4'want/gotandExpected:/Got:show the texts as writtenZeroDivisionErrorprint(5)for5.0print('Hallo')forHallo/hallo<function f at 0x0>for a function objectset()forset(){}forset()+NORMALIZE_WHITESPACEwith[1,2]+ELLIPSISwith[1, ...]+ELLIPSISwith4for4.0check-console-browser.mjs(test:console, Chrome with Pyodide):5for5.0, so value comparison is also checked in Pyodide.6instead of5for5.0), since5now passes.Locally green:
lint(the known warning),test:protocol,test:runtime,test:hints,build:embed+test:console.README («Tests (doctests)»): new paragraph, and the example «Erhalten: 4.0 · Erwartet: 4» (which now passes) changed to «Erhalten: 4.5 · Erwartet: 4». CLAUDE.md updated.
How it gets live
maindeploysdist-embed/to GitHub Pages (deploy-embed.yml). The macro loadshttps://glpython-edu.github.io/glpython-editor/index.htmllive in its iframe, and the macro itself doesn't change, so no version bump is needed.Cache-Control: max-age=600, so a browser that had the embed open may keep the old one for up to 10 minutes (or until a reload after that).index.htmlalways brings the new runtime.v0.1.21), then the tag inglpython/package.json(currently#v0.1.20). I'll prepare that PR in the IDE once the tag exists.Manual tests
Embed (LiaScript, Etappe 2, after the deploy and a reload):
>>> notenschnitt(4, 5, 6)/5: «Tests» passes, «1 von 1».>>> f()/[1,2,30]withreturn [1, 2, 30]: passes. With["+", 1, 2]andreturn ['+', 1, 2]: passes.>>> notenschnitt(4, 5, 6)/6): fails,Expected: 6,Got: 5.0; «Beispiel visualisieren» shows «Erhalten: 5.0 · Erwartet: 6».>>> 0.1 + 0.2/0.3: fails.@Code.rezept3): all pass with4for4.0→ the coverage still shows.printinstead ofreturn(expected5,print(5)): passes, with the print hint.IDE (after the bump): 1–3 in a file of its own.
Follow-ups (not done here)
materials/02-das-design-rezept/README.md) says the opposite: «Doctest vergleicht die Anzeige, nicht den Wert: Für Python ist4.0 == 4zwarTrue, … genau das muss unter dem Aufruf stehen.» Once this is live, that bullet is wrong. I didn't find other places in the course.Halloforreturn 'Hallo') still fails. That's a real type difference, not a display question; just mentioning it, since learners will meet it.🤖 Generated with Claude Code